﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Didaku.QEngine.Common.Abstracts.Entities;
using Didaku.QEngine.Common.Counts;
using Didaku.QEngine.Common.Entities;
using Didaku.QEngine.Methods.Adjust;
using Didaku.QEngine.Methods.Assign;
using Didaku.QEngine.Methods.ChangeLogic;
using Didaku.QEngine.Methods.Modify;
using NLog;

namespace Didaku.QEngine.Demo
{
    /// <summary>引擎工作的演示窗体
    /// </summary>
    public partial class DemoMainForm : Form
    {
        private static readonly Logger _Logger = LogManager.GetCurrentClassLogger();

        private bool _IsInitialized = false;

        private DepartmentInfo _Department;
        private Engine _Engine;
        private Transaction _CurrentTransaction;

        /// <summary>引擎工作的演示窗体
        /// </summary>
        public DemoMainForm()
        {
            InitializeComponent();
            _CloseEngineButton.Enabled = _IsInitialized;
            _TicketParamsGroupBox.Enabled = _IsInitialized;
            _TestTabControl.Enabled = _IsInitialized;
        }

        private void OpenEngineButtonClick(object sender, EventArgs e)
        {
            _Engine = new Engine();
            _Department = DepartmentMock.Get();
            _Engine.Initialize(_Department);
            _Engine.CountService.Counters.CountChangedEvent += CounterCountChangedEvent;
            _Engine.CountService.Queues.CountChangedEvent += QueueCountChangedEvent;
            _Engine.CountService.Elements.CountChangedEvent += ElementCountChangedEvent;
            _IsInitialized = true;
            _OpenEngineButton.Enabled = !_IsInitialized;
            _CloseEngineButton.Enabled = _IsInitialized;
            _TicketParamsGroupBox.Enabled = _IsInitialized;
            _TestTabControl.Enabled = _IsInitialized;
            _CounterCmbox.Items.Clear();

            FillDepartmentTree(_Department);
        }

        /// <summary>将Department中的选项显示在树中
        /// </summary>
        /// <param name="department"></param>
        private void FillDepartmentTree(DepartmentInfo department)
        {
            var view = _DepartmentTreeView;
            view.Nodes.Clear();
            var counterNode = new TreeNode("柜台");
            var bussNode = new TreeNode("业务");
            var staffNode = new TreeNode("员工");
            var cardNode = new TreeNode("卡片");
            var districtNode = new TreeNode("分区");
            view.Nodes.Add(counterNode);
            view.Nodes.Add(bussNode);
            view.Nodes.Add(staffNode);
            view.Nodes.Add(cardNode);
            view.Nodes.Add(districtNode);
            
            foreach (var counter in department.CounterMap.Values)
            {
                _CounterCmbox.Items.Add(counter.Index);
                var node = new TreeNode(counter.Name);
                counterNode.Nodes.Add(node);
                var logic = department.ServiceLogicMap[counter.Id];
                var logicNode = new TreeNode("ServiceLogic");
                foreach (var group in logic)
                {
                    var groupNode = new TreeNode(group.Name);
                    foreach (var queue in group)
                    {
                        var queueNode = new TreeNode(queue.Name);
                        foreach (var ele in queue.Elements)
                        {
                            var eleNode = new TreeNode(ele.GetType().Name+": "+ele.GetId());
                            queueNode.Nodes.Add(eleNode);
                        }
                        groupNode.Nodes.Add(queueNode);
                    }
                    logicNode.Nodes.Add(groupNode);
                }
                node.Nodes.Add(logicNode);
            }
            foreach (var buss in department.BusinessTypeMap.Values)
            {
                var node = new TreeNode(buss.Name);
                bussNode.Nodes.Add(node);
            }
            foreach (var card in department.CardCategoryMap.Values)
            {
                var node = new TreeNode(card.Name);
                cardNode.Nodes.Add(node);
            }
            foreach (var district in department.DistrictMap.Values)
            {
                var node = new TreeNode(district.Name);
                districtNode.Nodes.Add(node);
            }
            foreach (var staff in department.StaffMap.Values)
            {
                var node = new TreeNode(staff.Name);
                staffNode.Nodes.Add(node);
            }
        }

        private void GenerateTicketsButtonClick(object sender, EventArgs e)
        {
            foreach (var queueId in _Department.ServiceQueueMap.Keys)
            {
                int length = int.Parse(_GenerateTicketsCountComboBox.Text);
                for (int j = 0; j < length; j++)//队列的批量号票
                {
                    Transaction tran;
                    _Engine.Generate(out tran, queueId);
                }
            }
            _QueueTreeView.Nodes.Clear();
            foreach (var queue in _Engine.Queues.Values)
            {
                var queueNode = new TreeNode(queue.Name);
                _QueueTreeView.Nodes.Add(queueNode);
                foreach (var tran in queue)
                {
                    var tranNode = new TreeNode(tran.ToString());
                    queueNode.Nodes.Add(tranNode);
                }
            }
        }

        private void 顺呼(object sender, EventArgs e)
        {
            int counter = int.Parse(_CounterCmbox.Text);
            if (_CurrentTransaction != null)
                _CurrentTransaction.SetFinished();
            _Engine.Assign(out _CurrentTransaction,
                           new NormalCall
                           {
                               Counter = _Department.CounterMap.Values.ElementAt(counter),
                               Staff = _Department.StaffMap.Values.ElementAt(counter < 2 ? counter : counter / 2)
                           });
            Console.WriteLine("呼叫:" + _CurrentTransaction);
        }

        private void 并岗(string inputParams)
        {
            int counter1, counter2;
            string[] args = ParseParams(inputParams, out counter1);
            Int32.TryParse(args[2], out counter2);

            ICollection<Counter> counters = _Department.CounterMap.Values;
            Pair<string, string> condition = Pair<string, string>.Build(counters.ElementAt(counter1).Id, counters.ElementAt(counter2).Id);
            bool flag = _Engine.ChangeLogic(new CombineTargetCounter { Condition = condition });
            Console.WriteLine(flag ? "并岗成功" : "并岗失败");
        }

        private void 换岗(string inputParams)
        {
            int counter1, counter2;
            string[] args = ParseParams(inputParams, out counter1);
            Int32.TryParse(args[2], out counter2);

            ICollection<Counter> counters = _Department.CounterMap.Values;
            Pair<string, string> condition = Pair<string, string>.Build(counters.ElementAt(counter1).Id, counters.ElementAt(counter2).Id);
            bool flag = _Engine.ChangeLogic(new ReplaceWithTargetCounter { Condition = condition });
            Console.WriteLine(flag ? "换岗成功" : "换岗失败");
        }

        private void 转队(string inputParams)
        {
            int counter;
            string[] args = ParseParams(inputParams, out counter);
            Pair<Transaction, string> condition = Pair<Transaction, string>.Build(_CurrentTransaction, args[1]);
            bool flag = _Engine.Adjust(new MoveToQueue { Condition = condition });
            Console.WriteLine(flag ? _CurrentTransaction.TicketNumber + "转队成功" : _CurrentTransaction.TicketNumber + "转队失败");
        }

        private void 转柜台(string inputParams)
        {
            int counterIndex;
            string[] args = ParseParams(inputParams, out counterIndex);
            Counter counter = _Department.CounterMap.Values.ElementAt(counterIndex);
            Pair<Transaction, Counter> condition = Pair<Transaction, Counter>.Build(_CurrentTransaction, counter);
            bool flag = _Engine.Adjust(new MoveToCounter { Condition = condition });
            Console.WriteLine(flag ? _CurrentTransaction.TicketNumber + "转柜成功" : _CurrentTransaction.TicketNumber + "转柜失败");
        }

        private void 弃票(string inputParams)
        {
            int counter;
            string[] args = ParseParams(inputParams, out counter);

            if ((args.Length > 1 && !String.IsNullOrWhiteSpace(args[1])))
            {
                bool flag = _Engine.Modify(new GiveUpByTicketNumber { Condition = args[1].ToUpper() });
                Console.WriteLine(flag ? args[1] + "弃票成功" : args[1] + "弃票失败");
            }
            else
            {
                bool flag = _Engine.Modify(new GiveUpCurrent { Condition = _CurrentTransaction });
                Console.WriteLine(flag ? _CurrentTransaction.TicketNumber + "弃票成功" : _CurrentTransaction.TicketNumber + "弃票失败");
            }
        }

        private void 插前(string inputParams)
        {
            int counter;
            string[] args = ParseParams(inputParams, out counter);

            if ((args.Length > 1 && !String.IsNullOrWhiteSpace(args[1])))
            {
                bool flag = _Engine.Modify(new ForwardByTicketNumber { Condition = args[1].ToUpper() });
                Console.WriteLine(flag ? args[1] + "插前成功" : args[1] + "插前失败");
            }
        }

        private void 延后(string inputParams)
        {
            int counter;
            string[] args = ParseParams(inputParams, out counter);

            if ((args.Length > 1 && !String.IsNullOrWhiteSpace(args[1])))
            {
                bool flag = _Engine.Modify(new BackwardByTicketNumber { Condition = args[1].ToUpper() });
                Console.WriteLine(flag ? args[1] + "延后成功" : args[1] + "延后失败");
            }
            else
            {
                bool flag = _Engine.Modify(new BackwardCurrent { Condition = _CurrentTransaction });
                Console.WriteLine(flag ? _CurrentTransaction.TicketNumber + "延后成功" : _CurrentTransaction.TicketNumber + "延后失败");
            }
        }

        private void 指定呼叫(string inputParams)
        {
            int counter;
            string[] args = ParseParams(inputParams, out counter);

            if (args.Length > 2)
            {
                _Engine.Assign(out _CurrentTransaction,
                               new SpecifyCall
                                   {
                                       Counter = _Department.CounterMap.Values.ElementAt(counter),
                                       Staff = _Department.StaffMap.Values.ElementAt(counter < 2 ? counter : counter / 2),
                                       Condition = args[2].ToUpper()
                                   });
            }
            Console.WriteLine("指定呼叫:" + _CurrentTransaction);
        }

        private static void ElementCountChangedEvent(object sender, CountChangedEventArgs e)
        {
            //Console.WriteLine(String.Format("{0}:{1}", e.Item.ToString().Substring(0, 6).ToUpper(), e.Count));
        }

        private void QueueCountChangedEvent(object sender, CountChangedEventArgs e)
        {
            //ServiceQueue queue = _Department.ServiceQueueMap[e.Item];
            //Console.WriteLine(String.Format("{0}:{1}", queue.Name, e.Count));
        }

        private void CounterCountChangedEvent(object sender, CountChangedEventArgs e)
        {
            //Counter counter = _Department.CounterMap[(e.Item)];
            //Console.WriteLine(String.Format("{0}:{1}", counter.Name, e.Count));
        }

        private static string[] ParseParams(string inputParams, out int counter)
        {
            string[] args = inputParams.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            counter = 1;
            if (args.Length > 1)
                Int32.TryParse(args[1], out counter);
            return args;
        }
    }
}
